<template>
  <div class="map-container">
    <div id="map"></div>

    <div class="control-panel">
      <h3>地图控制</h3>
      <button @click="clearHighlight">清除高亮</button>
      <button @click="updateLayer">刷新图层</button>
      
      <!-- 绘图工具按钮 -->
      <div class="draw-tools">
        <h4>绘图工具</h4>
        <button 
          @click="toggleDraw('Point')" 
          :class="{ active: currentDrawType === 'Point' }"
          style="margin-top: 5px;"
        >
          绘制点
        </button>
        <button 
          @click="toggleDraw('LineString')" 
          :class="{ active: currentDrawType === 'LineString' }"
        >
          绘制线(测距)
        </button>
        <button 
          @click="toggleDraw('Polygon')" 
          :class="{ active: currentDrawType === 'Polygon' }"
        >
          绘制面
        </button>
        <button @click="clearDrawings" style="background-color: #ff9800;">
          清除绘图
        </button>
      </div>
      
      <button @click="goHome" style="margin-top: 10px; background-color: #ff6b6b;">返回首页</button>
    </div>

    <div class="legend">
      <h4>图例</h4>
      <div class="legend-item">
        <div class="legend-color" style="background-color: rgba(0, 200, 0, 0.5);"></div>
        <span>行政区划</span>
      </div>
      <div class="legend-item">
        <div class="legend-color" style="background-color: rgba(255, 255, 0, 0.8); border: 2px solid #ff0000;"></div>
        <span>选中区域</span>
      </div>
    </div>

    <div class="info-panel">
      <div>缩放级别: <span>{{ zoomLevel }}</span></div>
      <div>中心点: <span>{{ centerCoord }}</span></div>
      <div>图层状态: <span>{{ layerStatus }}</span></div>
      <div>点击要素: <span>{{ clickInfo }}</span></div>
      <!-- 添加测量信息显示 -->
      <div v-if="measureInfo">测量结果: <span>{{ measureInfo }}</span></div>
    </div>

    <div ref="popup" class="ol-popup">
      <a href="#" ref="popupCloser" class="ol-popup-closer"></a>
      <div ref="popupContent" id="popup-content"></div>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import VectorTileLayer from 'ol/layer/VectorTile';
import VectorLayer from 'ol/layer/Vector';
import XYZ from 'ol/source/XYZ';
import VectorTileSource from 'ol/source/VectorTile';
import VectorSource from 'ol/source/Vector';
import MVT from 'ol/format/MVT';
import Overlay from 'ol/Overlay';
import { fromLonLat, toLonLat } from 'ol/proj';
import { Circle, Fill, Stroke, Style } from 'ol/style';
import { Draw } from 'ol/interaction';
import { getLength, getArea } from 'ol/sphere';
import { unByKey } from 'ol/Observable';

export default defineComponent({
  name: 'PbfOpenLayer',
  setup() {
    const router = useRouter();
    
    // 响应式数据
    const zoomLevel = ref('-');
    const centerCoord = ref('-');
    const layerStatus = ref('未加载');
    const clickInfo = ref('无');
    const measureInfo = ref(''); // 测量信息
    const currentDrawType = ref(null); // 当前绘制类型
    
    // 引用DOM元素
    const popup = ref(null);
    const popupCloser = ref(null);
    const popupContent = ref(null);
    
    // 地图相关变量
    let map = null;
    let gaodeLayer = null;
    let pbfLayer = null;
    let highlightLayer = null;
    let drawLayer = null; // 绘图图层
    let popupOverlay = null;
    let selectedFeature = null;
    let drawInteraction = null; // 绘图交互
    let drawListener = null; // 绘图监听器

    // 返回首页
    const goHome = () => {
      router.push('/');
    };

    // 初始化地图
    const initMap = () => {
      // 创建高德地图图层
      gaodeLayer = new TileLayer({
        source: new XYZ({
          url: 'http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
          wrapX: true
        }),
        zIndex: 0
      });

      // 创建弹窗覆盖层
      popupOverlay = new Overlay({
        element: popup.value,
        autoPan: true,
        autoPanAnimation: {
          duration: 250
        }
      });

      // 创建地图
      map = new Map({
        target: 'map',
        layers: [gaodeLayer],
        view: new View({
          center: fromLonLat([113.2644, 23.1291]), // 广东省广州市附近
          zoom: 8,
          minZoom: 4,
          maxZoom: 18
        }),
        overlays: [popupOverlay]
      });

      // 添加高亮图层
      highlightLayer = new VectorLayer({
        source: new VectorSource(),
        style: createHighlightStyle(),
        zIndex: 100
      });
      map.addLayer(highlightLayer);

      // 添加绘图图层
      drawLayer = new VectorLayer({
        source: new VectorSource(),
        style: createDrawStyle(),
        zIndex: 90
      });
      map.addLayer(drawLayer);

      // 添加PBF图层
      addPbfLayer();

      // 添加点击事件
      map.on('click', function (evt) {
        // 如果正在绘制，则不处理PBF图层点击
        if (currentDrawType.value) return;
        
        // 清除之前的高亮
        clearHighlight();

        // 查找点击的要素
        const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
          return feature;
        }, {
          layerFilter: function (layer) {
            return layer === pbfLayer;
          }
        });

        if (feature) {
          // 高亮选中的图斑并显示信息
          highlightFeature(feature);
          showFeatureInfo(feature, evt.coordinate);
        } else {
          popupOverlay.setPosition(undefined);
          clickInfo.value = '无';
        }
      });

      // 鼠标悬停效果
      map.on('pointermove', function (evt) {
        // 如果正在绘制，显示绘制提示
        if (currentDrawType.value) {
          map.getTargetElement().title = '点击地图绘制，双击结束绘制';
          return;
        }
        
        const pixel = map.getEventPixel(evt.originalEvent);
        const hit = map.hasFeatureAtPixel(pixel, {
          layerFilter: function (layer) {
            return layer === pbfLayer;
          }
        });
        map.getTargetElement().style.cursor = hit ? 'pointer' : '';
      });

      // 弹窗关闭事件
      popupCloser.value.onclick = function () {
        clearHighlight();
        return false;
      };

      // 监听地图事件
      map.on('moveend', updateInfo);

      updateInfo();
    };

    // 添加PBF图层
    const addPbfLayer = () => {
      // 移除已存在的PBF图层
      if (pbfLayer) {
        map.removeLayer(pbfLayer);
      }

      // 创建PBF矢量瓦片源
      const vectorSource = new VectorTileSource({
        format: new MVT(),
        url: 'http://8.134.103.174:8081/pbf/guandongpbf/{z}/{x}/{y}.pbf',
        maxZoom: 14,
        minZoom: 4,
        wrapX: true
      });

      // 创建PBF矢量瓦片图层
      pbfLayer = new VectorTileLayer({
        source: vectorSource,
        style: createPbfStyle(),
        zIndex: 10
      });

      map.addLayer(pbfLayer);
      layerStatus.value = '已加载';
    };

    // 创建PBF图层样式
    const createPbfStyle = () => {
      return function (feature) {
        const geometryType = feature.getGeometry().getType();

        switch (geometryType) {
          case 'Point':
            return new Style({
              image: new Circle({
                radius: 5,
                fill: new Fill({
                  color: 'rgba(255, 0, 0, 0.7)'
                }),
                stroke: new Stroke({
                  color: '#ffffff',
                  width: 1
                })
              })
            });
          case 'LineString':
          case 'MultiLineString':
            return new Style({
              stroke: new Stroke({
                color: 'rgba(0, 0, 255, 0.7)',
                width: 2
              })
            });
          case 'Polygon':
          case 'MultiPolygon':
            return new Style({
              stroke: new Stroke({
                color: '#006600',
                width: 1
              }),
              fill: new Fill({
                color: 'rgba(0, 200, 0, 0.5)'
              })
            });
          default:
            return new Style({
              fill: new Fill({
                color: 'rgba(0, 0, 255, 0.5)'
              }),
              stroke: new Stroke({
                color: '#0000ff',
                width: 1
              })
            });
        }
      };
    };

    // 创建高亮样式
    const createHighlightStyle = () => {
      return function (feature) {
        const geometryType = feature.getGeometry().getType();

        switch (geometryType) {
          case 'Point':
            return new Style({
              image: new Circle({
                radius: 8,
                fill: new Fill({
                  color: 'rgba(255, 255, 0, 0.8)'
                }),
                stroke: new Stroke({
                  color: '#ff0000',
                  width: 2
                })
              })
            });
          case 'LineString':
          case 'MultiLineString':
            return new Style({
              stroke: new Stroke({
                color: 'rgba(255, 0, 0, 0.8)',
                width: 4
              })
            });
          case 'Polygon':
          case 'MultiPolygon':
            return new Style({
              stroke: new Stroke({
                color: '#ff0000',
                width: 3
              }),
              fill: new Fill({
                color: 'rgba(255, 255, 0, 0.8)'
              })
            });
          default:
            return new Style({
              fill: new Fill({
                color: 'rgba(255, 255, 0, 0.8)'
              }),
              stroke: new Stroke({
                color: '#ff0000',
                width: 2
              })
            });
        }
      };
    };

    // 创建绘图样式
    const createDrawStyle = () => {
      return function(feature) {
        const geometryType = feature.getGeometry().getType();
        
        switch (geometryType) {
          case 'Point':
            return new Style({
              image: new Circle({
                radius: 6,
                fill: new Fill({
                  color: '#3399CC'
                }),
                stroke: new Stroke({
                  color: '#fff',
                  width: 2
                })
              })
            });
          case 'LineString':
            return new Style({
              stroke: new Stroke({
                color: '#3399CC',
                width: 3
              })
            });
          case 'Polygon':
            return new Style({
              stroke: new Stroke({
                color: '#3399CC',
                width: 3
              }),
              fill: new Fill({
                color: 'rgba(51, 153, 204, 0.2)'
              })
            });
          default:
            return new Style({
              stroke: new Stroke({
                color: '#3399CC',
                width: 2
              }),
              fill: new Fill({
                color: 'rgba(51, 153, 204, 0.2)'
              })
            });
        }
      };
    };

    // 高亮选中的图斑
    const highlightFeature = (feature) => {
      // 保存当前选中的要素
      selectedFeature = feature;

      // 获取要素的属性
      const properties = feature.getProperties();

      // 创建新的高亮要素（直接引用原几何对象）
      const highlightFeature = feature.clone();

      // 添加到高亮图层
      highlightLayer.getSource().clear(); // 先清除之前的要素
      highlightLayer.getSource().addFeature(highlightFeature);

      // 更新信息面板
      const name = properties.name || properties.adcode || '未知区域';
      clickInfo.value = name;
    };

    // 显示要素信息
    const showFeatureInfo = (feature, coordinate) => {
      const properties = feature.getProperties();
      const geometry = feature.getGeometry();
      const geometryType = geometry.getType();

      // 构建弹窗内容
      let content = '<div class="popup-title">要素属性信息</div>';

      // 显示几何类型
      content += `<div class="popup-attribute"><span class="attr-name">几何类型:</span> ${geometryType}</div>`;

      // 显示属性信息
      for (let key in properties) {
        // 跳过几何属性和内部属性
        if (key !== 'geometry' && !key.startsWith('__') && properties[key] !== null && properties[key] !== undefined) {
          let value = properties[key];
          // 格式化复杂对象
          if (key === 'parent' && typeof value === 'object') {
            value = JSON.stringify(value);
          }
          if (key === 'acroutes' && Array.isArray(value)) {
            value = value.join(', ');
          }
          content += `<div class="popup-attribute"><span class="attr-name">${key}:</span> ${value}</div>`;
        }
      }

      // 显示坐标信息（对于点要素）
      if (geometryType === 'Point') {
        const coords = toLonLat(geometry.getCoordinates());
        content += `<div class="popup-attribute"><span class="attr-name">坐标:</span> ${coords[0].toFixed(6)}, ${coords[1].toFixed(6)}</div>`;
      }

      // 更新弹窗内容并显示
      popupContent.value.innerHTML = content;
      popupOverlay.setPosition(coordinate);
    };

    // 清除高亮
    const clearHighlight = () => {
      // 清除高亮图层中的所有要素
      highlightLayer.getSource().clear();

      // 清除选中状态
      selectedFeature = null;

      // 关闭弹窗
      popupOverlay.setPosition(undefined);

      // 更新信息面板
      clickInfo.value = '无';
    };

    // 切换绘制工具
    const toggleDraw = (type) => {
      // 如果点击的是当前激活的类型，则取消激活
      if (currentDrawType.value === type) {
        deactivateDraw();
        return;
      }
      
      // 先取消当前的绘制
      deactivateDraw();
      
      // 设置新的绘制类型
      currentDrawType.value = type;
      
      // 创建绘制交互
      drawInteraction = new Draw({
        source: drawLayer.getSource(),
        type: type,
        style: createDrawStyle()
      });
      
      // 添加绘制交互到地图
      map.addInteraction(drawInteraction);
      
      // 监听绘制事件
      if (type === 'LineString' || type === 'Polygon') {
        drawListener = drawInteraction.on('drawstart', function(evt) {
          // 清除之前的测量信息
          measureInfo.value = '';
        });
        
        drawInteraction.on('drawend', function(evt) {
          const feature = evt.feature;
          const geometry = feature.getGeometry();
          const geometryType = geometry.getType();
          
          // 计算并显示测量结果
          if (geometryType === 'LineString') {
            const length = getLength(geometry);
            const kilometers = length / 1000;
            measureInfo.value = `距离: ${kilometers.toFixed(2)} 公里`;
            alert(`长度：${measureInfo.value}公里`);
          } else if (geometryType === 'Polygon') {
            const area = getArea(geometry);
            const squareKilometers = area / 1000000;
            measureInfo.value = `面积: ${squareKilometers.toFixed(2)} 平方公里`;
            alert(`面积：${measureInfo.value}平方公里`);
          }
        });
      }
      
      // 提示用户如何操作
      alert(`已激活${type === 'Point' ? '点绘制' : type === 'LineString' ? '线绘制(测距)' : '面绘制'}模式\n点击地图开始绘制，${
        type === 'Point' ? '点击一次完成绘制' : '双击结束绘制'
      }`);
    };

    // 取消绘制
    const deactivateDraw = () => {
      if (drawInteraction) {
        map.removeInteraction(drawInteraction);
        drawInteraction = null;
      }
      if (drawListener) {
        unByKey(drawListener);
        drawListener = null;
      }
      currentDrawType.value = null;
      measureInfo.value = '';
    };

    // 清除所有绘制
    const clearDrawings = () => {
      if (drawLayer) {
        drawLayer.getSource().clear();
      }
      deactivateDraw();
      measureInfo.value = '';
    };

    // 更新图层
    const updateLayer = () => {
      try {
        addPbfLayer();
        clearHighlight();
        layerStatus.value = '更新成功';
      } catch (error) {
        layerStatus.value = '更新失败: ' + error.message;
      }
    };

    // 更新信息显示
    const updateInfo = () => {
      if (map) {
        const view = map.getView();
        zoomLevel.value = view.getZoom().toFixed(2);
        const center = toLonLat(view.getCenter());
        centerCoord.value = `${center[0].toFixed(6)}, ${center[1].toFixed(6)}`;
      }
    };

    onMounted(() => {
      initMap();
    });

    onBeforeUnmount(() => {
      if (map) {
        map.setTarget(null);
      }
    });

    return {
      zoomLevel,
      centerCoord,
      layerStatus,
      clickInfo,
      measureInfo,
      currentDrawType,
      popup,
      popupCloser,
      popupContent,
      clearHighlight,
      updateLayer,
      goHome,
      toggleDraw,
      clearDrawings
    };
  }
});
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}

#map {
  width: 100%;
  height: 100%;
}

.control-panel {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1000;
  background: white;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  max-width: 300px;
}

.control-panel h3 {
  margin-top: 0;
  color: #333;
}

.control-panel h4 {
  margin: 10px 0 5px 0;
  color: #666;
}

.control-panel button {
  background: #1e88e5;
  color: white;
  border: none;
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  width: 100%;
  margin-top: 10px;
}

.control-panel button:hover {
  background: #1976d2;
}

.control-panel button.active {
  background: #4caf50;
  box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
}

.info-panel {
  position: absolute;
  bottom: 10px;
  left: 10px;
  z-index: 1000;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  font-size: 12px;
}

.legend {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1000;
  background: white;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  max-width: 200px;
}

.legend h4 {
  margin-top: 0;
}

.legend-item {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.legend-color {
  width: 20px;
  height: 20px;
  margin-right: 10px;
  border: 1px solid #ccc;
}

.ol-popup {
  position: absolute;
  background-color: white;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
  padding: 15px;
  border-radius: 10px;
  border: 1px solid #cccccc;
  bottom: 12px;
  left: -50px;
  min-width: 280px;
  max-height: 300px;
  overflow-y: auto;
}

.ol-popup:after,
.ol-popup:before {
  top: 100%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none;
}

.ol-popup:after {
  border-top-color: white;
  border-width: 10px;
  left: 48px;
  margin-left: -10px;
}

.ol-popup:before {
  border-top-color: #cccccc;
  border-width: 11px;
  left: 48px;
  margin-left: -11px;
}

.ol-popup-closer {
  text-decoration: none;
  position: absolute;
  top: 2px;
  right: 8px;
  color: #666;
}

.ol-popup-closer:after {
  content: "✖";
}

.popup-title {
  font-weight: bold;
  margin-bottom: 10px;
  padding-bottom: 5px;
  border-bottom: 1px solid #eee;
}

.popup-attribute {
  margin-bottom: 5px;
}

.popup-attribute .attr-name {
  font-weight: bold;
  display: inline-block;
  width: 120px;
}
</style>